package com.snack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.snack.common.result.Result;
import com.snack.entity.pojo.Batch;
import com.snack.entity.pojo.BatchSnack;
import com.snack.entity.pojo.Snack;
import com.snack.entity.pojo.User;
import com.snack.mapper.BatchSnackMapper;
import com.snack.service.*;
import com.snack.utils.UserIdThreadLocal;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * @author huangfuhao
 * @Date 2025/3/29
 */
@Service
@Slf4j
public class BatchSnackServiceImpl extends ServiceImpl<BatchSnackMapper, BatchSnack> implements BatchSnackService {

    @Resource
    private SnackService snackService;

    @Resource
    private StoreService storeService;

    @Resource
    private BatchService batchService;

    @Override
    public Result addInventory(BatchSnack batchSnack) {

        //获取员工所在的店铺id
        Long storeId = storeService.getStoreIdByUser();
        //存储零食
        Long snackId = batchSnack.getSnackId();
        Long batchId = batchSnack.getBatchId();
        batchSnack.setStoreId(storeId);
        batchSnack.setState(0);
        Integer inventory = batchSnack.getInventory();

        log.info("批次id：{}，零食id：{}", batchId, snackId);
        //先将数据保存在库存_零食表
        boolean save = save(batchSnack);
        if (!save) {
            return Result.error("进货零食失败");
        }
        //根据零食id更新零食表当中零食的库存总量
        boolean update = snackService.lambdaUpdate().eq(Snack::getId, snackId).setSql("inventory = inventory + " + inventory).update();
        if (!update) {
            return Result.error("进货零食失败");
        }
        return Result.success("进货零食成功");
    }

    @Override
    public Result deleteInventory(BatchSnack batchSnack) {
        log.info("删除库存记录：{}", batchSnack);

        // 根据批次ID和零食ID查询库存记录是否存在
        LambdaQueryWrapper<BatchSnack> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BatchSnack::getBatchId, batchSnack.getBatchId())
                .eq(BatchSnack::getSnackId, batchSnack.getSnackId());
        BatchSnack existingBatchSnack = getOne(wrapper);

        if (existingBatchSnack == null) {
            return Result.error("库存记录不存在");
        }

        // 删除库存记录
        boolean delete = removeById(existingBatchSnack.getId());
        if (!delete) {
            return Result.error("删除失败");
        }

        // 更新零食表中的库存总量
        Long snackId = existingBatchSnack.getSnackId();
        Integer inventory = existingBatchSnack.getInventory();
        boolean snackUpdate = snackService.lambdaUpdate()
                .eq(Snack::getId, snackId)
                .setSql("inventory = inventory - " + inventory)
                .update();
        if (!snackUpdate) {
            return Result.error("更新零食库存失败");
        }

        return Result.success(existingBatchSnack);
    }


    @Override
    public Result listInventory(BatchSnack batchSnack) {
        // 列出该批次下存储了多少零食，还要列出零食的部分相关信息
        Long batchId = batchSnack.getBatchId();
        // 根据batchId查询
        List<BatchSnack> batchSnacks = lambdaQuery().eq(BatchSnack::getBatchId, batchId).list();

        if (batchSnacks == null || batchSnacks.isEmpty()) {
            return Result.success(new ArrayList<>());
        }

        return Result.success(batchSnacks);
    }

    @Override
    public Result updateInventory(BatchSnack batchSnack) {
        log.info("更新库存记录：{}", batchSnack);

        // 根据批次ID和零食ID查询库存记录是否存在
        LambdaQueryWrapper<BatchSnack> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BatchSnack::getBatchId, batchSnack.getBatchId())
                .eq(BatchSnack::getSnackId, batchSnack.getSnackId());
        BatchSnack existingBatchSnack = getOne(wrapper);

        if (existingBatchSnack == null) {
            return Result.error("库存记录不存在");
        }

        // 更新库存数量
        if (batchSnack.getInventory() != null) {
            existingBatchSnack.setInventory(batchSnack.getInventory());
        }

        // 更新生产日期
        if (batchSnack.getProductionDate() != null) {
            existingBatchSnack.setProductionDate(batchSnack.getProductionDate());
        }

        // 更新保质期
        if (batchSnack.getShelfLife() != null) {
            existingBatchSnack.setShelfLife(batchSnack.getShelfLife());
        }

        // 更新库存记录
        boolean update = updateById(existingBatchSnack);
        if (!update) {
            return Result.error("更新失败");
        }

        // 更新零食表中的库存总量
        Long snackId = existingBatchSnack.getSnackId();
        Integer inventoryChange = existingBatchSnack.getInventory() - batchSnack.getInventory();
        boolean snackUpdate = snackService.lambdaUpdate()
                .eq(Snack::getId, snackId)
                .setSql("inventory = inventory + " + inventoryChange)
                .update();
        if (!snackUpdate) {
            return Result.error("更新零食库存失败");
        }

        return Result.success(existingBatchSnack);
    }


    @Override
    public Result getExpiringSnacks() {
        log.info("获取临期零食列表");
        Long storeId = storeService.getStoreIdByUser();
        // 根据店铺id获取其拥有的所有未过期批次（state为0）
        LambdaQueryWrapper<Batch> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Batch::getStoreId, storeId)
                .eq(Batch::getState, 0);

        List<Batch> batches = batchService.list(queryWrapper);

        List<BatchSnack> expiringSnacks = new ArrayList<>();

        for (Batch batch : batches) {
            QueryWrapper<BatchSnack> batchSnackQueryWrapper = new QueryWrapper<>();
            batchSnackQueryWrapper.eq("batch_id", batch.getId()).eq("state", 0); // 根据批次id查询存储记录且未过期零食
            List<BatchSnack> batchSnacks = list(batchSnackQueryWrapper);

            for (BatchSnack batchSnack : batchSnacks) {
                LocalDate expirationDate = batchSnack.getProductionDate().plusMonths(batchSnack.getShelfLife());
                LocalDate now = LocalDate.now();
                long daysUntilExpiration = ChronoUnit.DAYS.between(now, expirationDate);

                if (daysUntilExpiration < 3) {
                    expiringSnacks.add(batchSnack);
                }
            }
        }

        return Result.success(expiringSnacks);
    }


}
